fix(peerclient): resolve base path per-call from live FrameTable#2585
fix(peerclient): resolve base path per-call from live FrameTable#2585
Conversation
After a peer→storage transition, peerSeekable kept opening base against the original (uncompressed) path captured at construction. With the recent compression work, post-transition reads now target a compressed object, so the cached base resolved to a non-existent path. P2P routing produced the stale binding (it captured a path while the build was still uncompressed); it also contains the fix. peerSeekable now holds (buildID, basic name, base provider, objType) and composes the actual storage path at base-open time using the CompressionType from the live FrameTable. The base seekable is reopened on ct change. No changes outside peerclient — no cache key, no chunker, no public storage interface. Also hoist the transition emit to the top of OpenRangeReader: returning PeerTransitionedError no longer wastes a base open before the caller swaps the header and retries.
❌ 7 Tests Failed:
View the full list of 17 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
There was a problem hiding this comment.
Code Review
The removal of nil checks for the uploaded atomic pointer in OpenRangeReader and tryPeer introduces potential nil pointer dereferences. A transition to storage occurring during a peer read attempt may be missed, causing the base storage to be opened with a stale compression type; re-checking the transition state after the peer attempt is necessary to ensure the caller refreshes the compression state correctly.
ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f1a2fab469
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…able boundary - StoreFile now returns an explicit error: peerSeekable only exists when routing picked an active peer at open time, so being asked to upload that build is a contradiction. Dead in production today (writes use bare persistence), but prevents a silent wrong-path write if a future caller routes one through. - Restore StripCompression in peerStorageProvider.OpenSeekable. Redis peer-key TTL outlives upload finalization by ~2 min; a fresh orchestrator can resolve a stale entry for a finalized V4/Zstd build, so StorageDiff hands us "buildID/memfile.zstd". Without stripping, getBase double-suffixes to "memfile.zstd.zstd" on fallthrough.
After a peer→storage transition, peerSeekable kept opening base against the original (uncompressed) path captured at construction. With the recent compression work, post-transition reads now target a compressed object, so the cached base resolved to a non-existent path.
P2P routing produced the stale binding (it captured a path while the build was still uncompressed); it also contains the fix. peerSeekable now holds (buildID, basic name, base provider, objType) and composes the actual storage path at base-open time using the CompressionType from the live FrameTable. The base seekable is reopened on ct change. No changes outside peerclient.